<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.6.7" />
<title>uthash ChangeLog</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */

/* Default font. */
body {
  font-family: Georgia,serif;
}

/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
  font-family: Arial,Helvetica,sans-serif;
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}
h5 {
  font-size: 1.0em;
}

div.sectionbody {
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}
ul > li     { color: #aaa; }
ul > li > * { color: black; }

pre {
  padding: 0;
  margin: 0;
}

#author {
  color: #527bbd;
  font-weight: bold;
  font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}

#footer {
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid #dddddd;
  border-left: 4px solid #f0f0f0;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid #dddddd;
  border-left: 5px solid #f0f0f0;
  background: #f8f8f8;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #f0f0f0;
  color: #888;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > pre.content {
  font-family: inherit;
  font-size: inherit;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}

div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}

div.colist td {
  padding-right: 0.5em;
  padding-bottom: 0.3em;
  vertical-align: top;
}
div.colist td img {
  margin-top: 0.3em;
}

@media print {
  #footer-badges { display: none; }
}

#toc {
  margin-bottom: 2.5em;
}

#toctitle {
  color: #527bbd;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}

span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }

span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }

span.big { font-size: 2em; }
span.small { font-size: 0.6em; }

span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }

div.unbreakable { page-break-inside: avoid; }


/*
 * xhtml11 specific
 *
 * */

tt {
  font-family: "Courier New", Courier, monospace;
  font-size: inherit;
  color: navy;
}

div.tableblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-weight: bold;
  color: #527bbd;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


/*
 * html5 specific
 *
 * */

.monospaced {
  font-family: "Courier New", Courier, monospace;
  font-size: inherit;
  color: navy;
}

table.tableblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
thead, p.tableblock.header {
  font-weight: bold;
  color: #527bbd;
}
p.tableblock {
  margin-top: 0;
}
table.tableblock {
  border-width: 3px;
  border-spacing: 0px;
  border-style: solid;
  border-color: #527bbd;
  border-collapse: collapse;
}
th.tableblock, td.tableblock {
  border-width: 1px;
  padding: 4px;
  border-style: solid;
  border-color: #527bbd;
}

table.tableblock.frame-topbot {
  border-left-style: hidden;
  border-right-style: hidden;
}
table.tableblock.frame-sides {
  border-top-style: hidden;
  border-bottom-style: hidden;
}
table.tableblock.frame-none {
  border-style: hidden;
}

th.tableblock.halign-left, td.tableblock.halign-left {
  text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
  text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
  text-align: right;
}

th.tableblock.valign-top, td.tableblock.valign-top {
  vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
  vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
  vertical-align: bottom;
}


/*
 * manpage specific
 *
 * */

body.manpage h1 {
  padding-top: 0.5em;
  padding-bottom: 0.5em;
  border-top: 2px solid silver;
  border-bottom: 2px solid silver;
}
body.manpage h2 {
  border-style: none;
}
body.manpage div.sectionbody {
  margin-left: 3em;
}

@media print {
  body.manpage div#toc { display: none; }
}
@media screen {
  body {
    max-width: 50em; /* approximately 80 characters wide */
    margin-left: 16em;
  }

  #toc {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 13em;
    padding: 0.5em;
    padding-bottom: 1.5em;
    margin: 0;
    overflow: auto;
    border-right: 3px solid #f8f8f8;
    background-color: white;
  }

  #toc .toclevel1 {
    margin-top: 0.5em;
  }

  #toc .toclevel2 {
    margin-top: 0.25em;
    display: list-item;
    color: #aaaaaa;
  }

  #toctitle {
    margin-top: 0.5em;
  }
}
</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  if (!toc) {
    return;
  }

  // Delete existing TOC entries in case we're reloading the TOC.
  var tocEntriesToRemove = [];
  var i;
  for (i = 0; i < toc.childNodes.length; i++) {
    var entry = toc.childNodes[i];
    if (entry.nodeName.toLowerCase() == 'div'
     && entry.getAttribute("class")
     && entry.getAttribute("class").match(/^toclevel/))
      tocEntriesToRemove.push(entry);
  }
  for (i = 0; i < tocEntriesToRemove.length; i++) {
    toc.removeChild(tocEntriesToRemove[i]);
  }

  // Rebuild TOC entries.
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  // Delete existing footnote entries in case we're reloading the footnodes.
  var i;
  var noteholder = document.getElementById("footnotes");
  if (!noteholder) {
    return;
  }
  var entriesToRemove = [];
  for (i = 0; i < noteholder.childNodes.length; i++) {
    var entry = noteholder.childNodes[i];
    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
      entriesToRemove.push(entry);
  }
  for (i = 0; i < entriesToRemove.length; i++) {
    noteholder.removeChild(entriesToRemove[i]);
  }

  // Rebuild footnote entries.
  var cont = document.getElementById("content");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      var note = spans[i].getAttribute("data-note");
      if (!note) {
        // Use [\s\S] in place of . so multi-line matches work.
        // Because JavaScript has no s (dotall) regex flag.
        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
        spans[i].innerHTML =
          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
        spans[i].setAttribute("data-note", note);
      }
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
},

install: function(toclevels) {
  var timerId;

  function reinstall() {
    asciidoc.footnotes();
    if (toclevels) {
      asciidoc.toc(toclevels);
    }
  }

  function reinstallAndRemoveTimer() {
    clearInterval(timerId);
    reinstall();
  }

  timerId = setInterval(reinstall, 500);
  if (document.addEventListener)
    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
  else
    window.onload = reinstallAndRemoveTimer;
}

}
asciidoc.install(2);
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>uthash ChangeLog</h1>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>Click to return to the <a href="index.html">uthash home page</a>.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">uthash is no longer maintained as of 2015.</td>
</tr></table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_9_1_2014_11_18">Version 1.9.9.1 (2014-11-18)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
inclusion of experimental libut bundle with utvector in opt/
</p>
</li>
<li>
<p>
use shift in Bernstein hash instead of multiply (thanks, Jimmy Zhuo!)
</p>
</li>
<li>
<p>
switch ssize_t types in utarray/utstring to size_t (thanks, Hong Xu!)
</p>
</li>
<li>
<p>
fix utstring pointer math on &gt;4GB strings (thanks, Thomas Bottesch!)
</p>
</li>
<li>
<p>
change FNV hash to FNV-1a varation (thanks, dwest1975!)
</p>
</li>
<li>
<p>
fix bug in HASH_REPLACE_STR (thanks, Ilya Kaliman!)
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_9_2014_02_25">Version 1.9.9 (2014-02-25)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
made HASH_ADD_STR compatible with char* or char[] (thanks, Samuel Thibault!)
</p>
</li>
<li>
<p>
fixed header inclusion of sys/types.h for ssize_t (thanks, Fernando Campos!)
</p>
</li>
<li>
<p>
added LL_COUNT/DL_COUNT/CDL_COUNT (thansk, Paul Praet!)
</p>
</li>
<li>
<p>
added LRU cache example in <tt>tests/lru_cache</tt> (thanks, Oliver Lorenz!)
</p>
</li>
<li>
<p>
fix LL_DELETE2 for VS2008 (thanks, Greg Davydouski!)
</p>
</li>
<li>
<p>
fix missing argument in <tt>HASH_REPLACE_STR</tt> (thanks, Alex!)
</p>
</li>
<li>
<p>
bump version number in source files to match docs (thanks, John Crow!)
</p>
</li>
<li>
<p>
add <tt>HASH_OVERHEAD</tt> macro to get overhead size for hash table
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_8_2013_03_10">Version 1.9.8 (2013-03-10)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
<tt>HASH_REPLACE</tt> now in uthash (thanks, Nick Vatamaniuc!)
</p>
</li>
<li>
<p>
fixed clang warnings (thanks wynnw!)
</p>
</li>
<li>
<p>
fixed <tt>utarray_insert</tt> when inserting past array end (thanks Rob Willett!)
</p>
</li>
<li>
<p>
you can now find <a href="http://troydhanson.github.com/uthash/">uthash on GitHub</a>
</p>
</li>
<li>
<p>
there&#8217;s a <a href="https://groups.google.com/d/forum/uthash">uthash Google Group</a>
</p>
</li>
<li>
<p>
uthash has been downloaded 29,000+ times since 2006 on SourceForge
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_7_2012_10_09">Version 1.9.7 (2012-10-09)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
utstring now supports substring search using <tt>utstring_find</tt> (thanks, Joe Wei!)
</p>
</li>
<li>
<p>
utlist now supports element <em>prepend</em> and <em>replace</em> (thanks, Zoltán Lajos Kis!)
</p>
</li>
<li>
<p>
utlist element prev/next fields can now have any names (thanks, Pawel S. Veselov!)
</p>
</li>
<li>
<p>
uthash cast quiets a clang warning (thanks, Roman Divacky and Baptiste Daroussin!)
</p>
</li>
<li>
<p>
uthash userguide example shows how to check key uniqueness (thanks, Richard Cook!)
</p>
</li>
<li>
<p>
uthash HASH_MUR compiles under MSVC++ 10 in C mode (thanks, Arun Kirthi Cherian!)
</p>
</li>
<li>
<p>
<tt>utstring_printf</tt> now supports format checking (thanks, Donald Carr!)
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_6_2012_04_28">Version 1.9.6 (2012-04-28)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
add utarray_prev (thanks, Ben Hiett!)
</p>
</li>
<li>
<p>
add parens/casts for greater compatibility (thanks, Atis, Debasis Ganguly, and Steve McClellan!)
</p>
</li>
<li>
<p>
added ifndef to uthash_malloc and related hooks (thanks, Holger Machens!)
</p>
</li>
<li>
<p>
edit examples so they do not leak memory (thanks, 任晶磊!)
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_5_2011_11_16">Version 1.9.5 (2011-11-16)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
added <tt>utarray_renew</tt>
</p>
</li>
<li>
<p>
fixed memory leak in <tt>uthash_clear</tt> when using Bloom filter (thanks, Jan Hättig!)
</p>
</li>
<li>
<p>
utarray now copies the UT_icd on array creation rather than storing a pointer
</p>
</li>
<li>
<p>
add parentheses to <tt>HASH_ADD</tt> to fix preprocessing of certain arguments (thanks, Aaron Rosen!)
</p>
</li>
<li>
<p>
more parenthesizations for greater macro argument flexibility
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_4_2011_06_05">Version 1.9.4 (2011-06-05)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
uthash now supports MurmurHash v3
</p>
</li>
<li>
<p>
utlist now includes concatenation macros (<tt>LL_CONCAT</tt> and <tt>DL_CONCAT</tt>)
</p>
</li>
<li>
<p>
utarray now supports binary search (<tt>utarray_find</tt>)
</p>
</li>
<li>
<p>
utstring now supports a new-or-clear-existing macro (<tt>utstring_renew</tt>)
</p>
</li>
<li>
<p>
documented technique for a multi-level hash table
</p>
</li>
<li>
<p>
clarified scope requirements for <tt>UT_icd</tt> in the utarray documentation
</p>
</li>
<li>
<p>
fixed termination when <tt>utstring_clear</tt> is followed by <tt>utstring_body</tt>
</p>
</li>
<li>
<p>
fixed utarray_inserta macro when used with complex arguments
</p>
</li>
<li>
<p>
on Visual Studio define missing type <tt>uint8_t</tt>
</p>
</li>
<li>
<p>
Debian/Ubuntu include uthash in the package <tt>uthash-dev</tt>.
</p>
</li>
<li>
<p>
uthash has been downloaded 16,211 times.
</p>
</li>
</ul></div>
<div class="paragraph"><p>Thanks to Yu Feng, Richard Cook, Dino Ciuffetti, Chris Groer, and Arun Cherian
for feedback and fixes in this release!</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_3_2010_10_31">Version 1.9.3 (2010-10-31)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
fix an <tt>ifdef</tt> for compatibility with Intel compiler (thanks, degski!)
</p>
</li>
<li>
<p>
fix <tt>HASH_ITER</tt> macro to satisfy C++ casting rules (thanks, Erik Bai!)
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_2_2010_10_04">Version 1.9.2 (2010-10-04)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
new <tt>HASH_ITER</tt> macro for more convenient deletion-safe iteration
</p>
</li>
<li>
<p>
<tt>hashscan</tt> can now run on FreeBSD 8.1 and later (thanks, Markus Gebert!)
</p>
</li>
<li>
<p>
More parens to evaluate complex macro arguments properly (thanks, ngg!)
</p>
</li>
<li>
<p>
Add sz parameter to the <tt>uthash_free</tt> hook for platforms that do their own memory management. Hopefully this minor API change doesn&#8217;t cause too much breakage for people. (thanks, Niall Douglas!)
</p>
</li>
<li>
<p>
uthash has been downloaded 12,294 times
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_1_2010_05_15">Version 1.9.1 (2010-05-15)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Fix a redefinition warning when using <tt>uthash.h</tt> and <tt>utstring.h</tt> together
</p>
</li>
<li>
<p>
Fix a bug in <tt>utstring_init</tt>
</p>
</li>
<li>
<p>
Added <tt>HASH_FIND_PTR</tt> and <tt>HASH_ADD_PTR</tt> (thanks, Niall Douglas!)
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_9_2010_03_31">Version 1.9 (2010-03-31)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
uthash now supports Visual Studio 2008 and 2010 in C or C++ code!
</p>
</li>
<li>
<p>
new headers <a href="utarray.html">utarray.h</a> and <a href="utstring.html">utstring.h</a>
        are now included. These implement dynamic arrays and strings using macros
</p>
</li>
<li>
<p>
<a href="utlist.html">utlist.h</a> now has deletion-safe iterators and search macros
</p>
</li>
<li>
<p>
the test suite now runs under Visual Studio (thanks again degski!)
</p>
</li>
<li>
<p>
special thanks for suggesting utarray and utlist features to Charalampos P.!
</p>
</li>
<li>
<p>
uthash has been downloaded 9,616 times
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_8_2009_09_08">Version 1.8 (2009-09-08)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Added the <tt>hashscan</tt> utility that can report on the size and quality of
  hash tables in a running process (Linux-only)
</p>
</li>
<li>
<p>
Added Bloom filter support. This has the potential to speed up certain
  types of programs that look up non-existant keys in sufficient numbers.
</p>
</li>
<li>
<p>
Restored the MurmurHash, which can once again be used, if an additional
  symbol is defined. This is a "safety" by which the user declares they
  understand that <tt>-fno-strict-aliasing</tt> flag must be used if they are
  using MurmurHash under gcc with optimization.
</p>
</li>
<li>
<p>
Unified the bucket/table malloc hooks; now there is only one malloc hook
</p>
</li>
<li>
<p>
Re-organized the manual into a main section and advanced topics section
</p>
</li>
<li>
<p>
Fixed a bug in <tt>utlist.h</tt> where sorting a singly-linked list threw a
  compile-time error.
</p>
</li>
<li>
<p>
Fixed a bug in <tt>utlist.h</tt> where a doubly-linked list that is sorted
  did not maintain the special <tt>head-&gt;prev</tt> pointer back to the list tail.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_7_2009_06_11">Version 1.7 (2009-06-11)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
The MurmurHash has been removed, and Jenkin&#8217;s hash is once again the default.
  While MurmurHash performed well, it&#8217;s unsafe with regard to the strict
  aliasing rule. This results in incorrect code when compiled with optimization.
  It&#8217;s not possible to enable <tt>-fno-strict-aliasing</tt> from within a header file.
</p>
</li>
<li>
<p>
The linked list macros in <tt>utlist.h</tt> now comply with the strict-aliasing
  rule so they generate correct code under high optimization levels (O2 or O3).
  The use of the <tt>__typeof__</tt> extension, which was originally a GNU extension,
  may reduce portability to other compilers that do not support this extension.
  This extension is used in the singly-linked list macros and the sort macros.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_6_2009_05_08">Version 1.6 (2009-05-08)</h2>
<div class="sectionbody">
<div class="paragraph"><p>Special thanks to Alfred Heisner for contributing several enhancements:</p></div>
<div class="ulist"><ul>
<li>
<p>
Support for two new hash functions:
</p>
<div class="ulist"><ul>
<li>
<p>
the Paul Hsieh hash function (<tt>HASH_SFH</tt>)
</p>
</li>
<li>
<p>
Austin Appleby&#8217;s MurmurHash function (<tt>HASH_MUR</tt>)
</p>
</li>
</ul></div>
</li>
<li>
<p>
Because of its excellent performance, MurmurHash is now the default hash function.
</p>
</li>
<li>
<p>
<tt>keystats</tt> now has much better elapsed time accuracy under Cygwin and MinGW
</p>
</li>
<li>
<p>
fixed casting in <tt>HASH_FNV</tt>, <tt>HASH_SAX</tt> and <tt>HASH_OAT</tt> for non-char keys
</p>
</li>
</ul></div>
<div class="paragraph"><p>This release also includes:</p></div>
<div class="ulist"><ul>
<li>
<p>
a new <tt>HASH_CLEAR</tt> operation clears a hash table in one step.
</p>
</li>
<li>
<p>
a new <tt>HASH_SELECT</tt> operation inserts those elements from one hash that
  satisfy a given condition into another hash. The selected items have
  dual presence in both hash tables. For example a game could select the
  visible polygons from a hash of all polygons.
</p>
</li>
<li>
<p>
fixed a compile-time error which occurred if the final argument to
  <tt>HASH_ADD_KEYPTR</tt> was a pointer to an array member like <tt>&amp;a[i]</tt>
</p>
</li>
<li>
<p>
added another test script <tt>tests/all_funcs</tt> which executes the test suite
  using every supported hash function
</p>
</li>
</ul></div>
<div class="paragraph"><p>And lastly,</p></div>
<div class="ulist"><ul>
<li>
<p>
a new, separate header called <a href="utlist.html">utlist.h</a> is included which
  provides <em>linked list macros</em> for C structures, similar in style to the
  uthash macros
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_5_2009_02_19">Version 1.5 (2009-02-19)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
now thread-safe for concurrent readers
</p>
</li>
<li>
<p>
use scratch variables on stack rather than in table (thanks, Petter Arvidsson!).
  This change made HASH_FIND about 13% faster and enabled reader concurrency.
</p>
</li>
<li>
<p>
made <a href="license.html">BSD license</a> terms even more permissive
</p>
</li>
<li>
<p>
added <a href="userguide.pdf">PDF version</a> of User Guide
</p>
</li>
<li>
<p>
added <a href="http://troydhanson.wordpress.com/feed/">update news</a> <span class="image">
<img src="rss.png" alt="(RSS)" />
</span>
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_4_2008_09_23">Version 1.4 (2008-09-23)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Add <tt>HASH_COUNT</tt> for counting items in the hash
</p>
</li>
<li>
<p>
Compatibility with C++. Satisfy additional casting requirements.
  Also in the <tt>tests/</tt> directory, running <tt>make cplusplus</tt> now compiles
  all the test programs with the C++ compiler.
</p>
</li>
<li>
<p>
Eliminate <tt>elmt</tt> pointer from the UT_hash_handle. Calculate elmt
  from hash handle address by subtracting <tt>hho</tt> (hash handle offset).
</p>
</li>
<li>
<p>
Contributed by L.S.Chin:
  Cast <tt>void*</tt> to char* before pointer arithmetic to suppress compiler
  warnings. We assume compilers abide to C standards which impose
  requirement that <tt>sizeof(void*) == sizeof(char*)</tt>.
</p>
</li>
<li>
<p>
Return meaningful exit status from do_tests per Tiago Cunha,
  so that package manager-based install can verify tests are successful
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_3_2008_07_27">Version 1.3 (2008-07-27)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
use integer-only math-- no floating point! Support FPU-less CPU&#8217;s.
</p>
</li>
<li>
<p>
eliminate <tt>hash_q</tt> metric, which measured the fraction of items with
  non-ideal chain positions. We only need to know if this fraction
  is below 0.5. This is now determined using fast bitwise tests.
</p>
</li>
<li>
<p>
when an item is added to the hash, calculate the key&#8217;s hash value
  upfront and store it, instead of recomputing it as needed. This hashv
  is stored in the hash handle. Potentially major speed benefit for
  bucket expansion algorithm. Deleting is marginally improved too.
</p>
</li>
<li>
<p>
fixed a minor bug in the calculation of the max ideal chain length;
  line 446 in v1.2 erroneously calculated a/b*2 instead of a/(b*2).
  The effect of this bug was that bucket expansion could occur more
  readily because the per-bucket <em>max chain length multiplier factor</em>
  (which delays bucket expansion when certain buckets are overused)
  was set to a lower, expansion-favoring value than intended.
</p>
</li>
<li>
<p>
improved source commenting and improved variable names in structures
</p>
</li>
<li>
<p>
remove <tt>HASH_JSW</tt>. Lengthy random number array made code less readable
</p>
</li>
<li>
<p>
add <tt>HASH_SRT(hh,hash,cmp)</tt> as a generalized <tt>HASH_SORT(hash,cmp)</tt>.
  It was an omission in uthash 1.2 that there was no sort macro for
  hash handles with names other than hh.
</p>
</li>
<li>
<p>
Corrected <tt>HASH_FSCK</tt> so it works with any name for the hash handle.
</p>
</li>
<li>
<p>
behave properly in pathological <tt>HASH_DEL(a,a)</tt> case where the same
  variable references the head and the deletee (advancing the head
  then loses the correct reference to the deletee); fix by using
  scratch area in the hash table to store deletee hash handle.
</p>
</li>
<li>
<p>
made tests runnable on MinGW
</p>
</li>
<li>
<p>
3000+ downloads since uthash-1.0
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_2_2006_11_22">Version 1.2 (2006-11-22)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
new <tt>HASH_SORT</tt> macro
</p>
</li>
<li>
<p>
Cygwin support
</p>
</li>
<li>
<p>
User Guide now features a clickable Table of Contents.
  (The technique for generating the TOC on the browser was contributed
  back to the AsciiDoc project and incorporated into AsciiDoc v8.1.0).
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_1_2006_06_28">Version 1.1 (2006-06-28)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
uthash-1.1 released
</p>
</li>
<li>
<p>
supports several built-in user-selectable hash functions
</p>
</li>
<li>
<p>
new keystats utility quantifies performance of hash functions
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_version_1_0_2006_06_02">Version 1.0 (2006-06-02)</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Initial release
</p>
</li>
</ul></div>
</div>
</div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated 2014-11-18 21:28:59 EST
</div>
</div>
</body>
</html>
